package qms


import grails.converters.*
import grails.test.mixin.*
import org.junit.*

/**
 * See the API for {@link grails.test.mixin.web.ControllerUnitTestMixin} for usage instructions
 */
@TestFor(IndexController)
@Mock([Organisation, Unit, Project, Employee])
class IndexControllerTests {

	void testIdex() {
		controller.index()
		assert response.status == 200
	}

	// ======================= READ ======================= 

	void testReadTree() {
		def org = new Organisation(name: "Main", description: "description goes here")
		org.save()

		def unit1 = new Unit(name: "Unit", description: "description")
		org.addToUnits(unit1)
		unit1.save()
		
		def project1 = new Project(name: "Project 1", description: "empty")
		unit1.addToProjects(project1)
		project1.save()

		def empl1 = new Employee(name: "Vasya", surName: "Pupkin", email:"vasya@mail.pu", birthDay: Date.parse("yyyy-MM-dd", "2009-09-15"), dateEmployed: Date.parse("yyyy-MM-dd", "2009-09-15"))
		project1.addToEmployees(empl1)
		empl1.save()

		params.do_action = 'read'
		params.node = 'root'
		controller.orgTree()

		assert [
				root:[
					id: 'ORG-1',
					text: 'Main',
					leaf: false,
					expanded: true,
					root: [
						[
							id: 'UNIT-1',
							text: 'Unit',
							leaf: false,
							expanded: true,
							root: [
								[
									id: 'PROJ-1',
									text: 'Project 1',
									leaf: false,
									expanded: true,
									root: [
										[
											id: 'EMPL-1',
											text: 'Vasya Pupkin',
											leaf: true
										]
									]
								]
							]
						]
					]
				]
			] == response.json
		assert response.status == 200
		assert Organisation.count() == 1
		assert Unit.count() == 1
		assert Project.count() == 1
		assert Employee.count() == 1
	}

	void testReadOrganisation() {
		def org = new Organisation(name: "Main", description: "description goes here")
		org.save()

		params.do_action = 'read'
		request.JSON = [id: 1]

		controller.organisation(request)
		assert [root: [id: 1, name: "Main", description: "description goes here"]] == response.json
		assert Organisation.count() == 1
	}

	void testReadUnit() {
		def org = new Organisation(name: "Main", description: "description goes here")
		org.save()

		def unit1 = new Unit(name: "Unit", description: "description")
		org.addToUnits(unit1)
		unit1.save()

		params.do_action = 'read'
		request.JSON = [id: 1]
		controller.unit(request)

		assert response.status == 200
		assert [root: [id: 1, name: "Unit", description: "description"]] == response.json
		assert Organisation.count() == 1
		assert Unit.count() == 1
	}

	void testReadProject() {
		def org = new Organisation(name: "Main", description: "description goes here")
		org.save()

		def unit1 = new Unit(name: "Unit", description: "description")
		org.addToUnits(unit1)
		unit1.save()

		def project1 = new Project(name: "Project 1", description: "empty")
		unit1.addToProjects(project1)
		project1.save()

		params.do_action = 'read'
		request.JSON = [id: 1]
		controller.project(request)

		assert response.status == 200
		assert [root: [id: 1,name: "Project 1", description: "empty"]] == response.json
		assert Organisation.count() == 1
		assert Unit.count() == 1
		assert Project.count() == 1
	}

	void testReadEmployee() {
		def org = new Organisation(name: "Main", description: "description goes here")
		org.save()

		def unit1 = new Unit(name: "Unit", description: "description")
		org.addToUnits(unit1)
		unit1.save()

		def project1 = new Project(name: "Project 1", description: "empty")
		unit1.addToProjects(project1)
		project1.save()

		def empl1 = new Employee(name: "Vasya", surName: "Pupkin", email:"vasya@mail.pu", birthDay: Date.parse("yyyy-MM-dd", "2009-09-15"), dateEmployed: Date.parse("yyyy-MM-dd", "2009-09-15"))
		project1.addToEmployees(empl1)
		empl1.save()

		params.do_action = 'read'
		request.JSON = [id: 1]
		controller.employee(request)

		assert response.status == 200
		assert [root: [id: 1, name: "Vasya", surName: "Pupkin", email:"vasya@mail.pu", dateEmployed:'2009-09-14T20:00:00Z', birthDay:'2009-09-14T20:00:00Z']] == response.json
		assert Organisation.count() == 1
		assert Unit.count() == 1
		assert Project.count() == 1
		assert Employee.count() == 1
	}

	// ======================= SAVE ======================= 

	void testSaveUnit() {
		def org = new Organisation(name: "Main", description: "description goes here")
		org.save()

		params.do_action = 'create'
		request.JSON = [parentId: "ORG-1", description: "description goes here", name: "Unit"]

		controller.orgTree(request)

		assert response.status == 200
		assert [root: [id: 'UNIT-1', parentId: 'ORG-1', text: 'Unit', leaf: false]] == response.json
		assert Organisation.count() == 1
		assert Unit.count() == 1
	}

	void testSaveUnitBad() {
		def org = new Organisation(name: "Main", description: "description goes here")
		org.save()

		params.do_action = 'create'
		request.JSON = [parentId: "ORG-1", description: "description goes here"] // No name

		controller.orgTree(request)

		assert response.status == 500
		assert '' == response.text
		assert Organisation.count() == 1
		assert Unit.count() == 0
	}

	void testSaveProject() {
		def org = new Organisation(name: "Main", description: "description goes here")
		org.save()

		def unit1 = new Unit(name: "Unit", description: "description")
		org.addToUnits(unit1)
		unit1.save()

		params.do_action = 'create'
		request.JSON = [parentId: "UNIT-1", description: "empty", name: "Project 1"]
		controller.orgTree(request)

		assert response.status == 200
		assert [root: [parentId: "UNIT-1", id: "PROJ-1", text: "Project 1", leaf: false]] == response.json
		assert Organisation.count() == 1
		assert Unit.count() == 1
		assert Project.count() == 1
	}

	void testSaveProjectBad() {
		def org = new Organisation(name: "Main", description: "description goes here")
		org.save()

		def unit1 = new Unit(name: "Unit", description: "description")
		org.addToUnits(unit1)
		unit1.save()

		params.do_action = 'create'
		request.JSON = [parentId: "UNIT-1", description: "empty",]
		controller.orgTree(request)

		assert response.status == 500
		assert '' == response.text
		assert Organisation.count() == 1
		assert Unit.count() == 1
		assert Project.count() == 0
	}

	void testSaveEmployee() {
		def org = new Organisation(name: "Main", description: "description goes here")
		org.save()

		def unit1 = new Unit(name: "Unit", description: "description")
		org.addToUnits(unit1)
		unit1.save()

		def project1 = new Project(name: "Project 1", description: "empty")
		unit1.addToProjects(project1)
		project1.save()

		params.do_action = 'create'
		request.JSON = [parentId: "PROJ-1", name: "John", surName: "Coner", email:"johnconer@gmail.com", birthDay: Date.parse("yyyy-MM-dd", "1999-09-15"), dateEmployed: Date.parse("yyyy-MM-dd", "2029-09-15")]
		controller.orgTree(request)

		assert response.status == 200
		assert [root: [parentId: "PROJ-1", id: "EMPL-1", text: "John Coner", leaf: true]] == response.json
		assert Organisation.count() == 1
		assert Unit.count() == 1
		assert Project.count() == 1
		assert Employee.count() == 1
	}

	void testSaveEmployeeBad() {
		def org = new Organisation(name: "Main", description: "description goes here")
		org.save()

		def unit1 = new Unit(name: "Unit", description: "description")
		org.addToUnits(unit1)
		unit1.save()

		def project1 = new Project(name: "Project 1", description: "empty")
		unit1.addToProjects(project1)
		project1.save()

		params.do_action = 'create'
		request.JSON = [parentId: "PROJ-1", name: "John", surName: "Coner"]
		controller.orgTree(request)

		assert response.status == 500
		assert '' == response.text
		assert Organisation.count() == 1
		assert Unit.count() == 1
		assert Project.count() == 1
		assert Employee.count() == 0
	}
	// ======================= UPDATE ======================= 

	void testUpdateOrganisation() {
		def org = new Organisation(name: "Main", description: "description goes here")
		org.save()

		params.do_action = 'update'
		request.JSON = [id: 1, description: "new description goes here", name: "Organisation"]
		controller.organisation(request)

		assert response.status == 200
		assert [root: [id: 1, name: "Organisation", description: "new description goes here"]] == response.json
		assert Organisation.count() == 1
	}

	void testUpdateUnit() {
		def org = new Organisation(name: "Main", description: "description goes here")
		org.save()

		def unit1 = new Unit(name: "Unit", description: "description")
		org.addToUnits(unit1)
		unit1.save()

		params.do_action = 'update'
		request.JSON = [id: 1, description: "new description goes here", name: "Update Unit"]
		controller.unit(request)

		assert response.status == 200
		assert [root: [id: 1, name: 'Update Unit', description: "new description goes here"]] == response.json
		assert Organisation.count() == 1
		assert Unit.count() == 1
	}

	void testUpdateProject() {
		def org = new Organisation(name: "Main", description: "description goes here")
		org.save()

		def unit1 = new Unit(name: "Unit", description: "description")
		org.addToUnits(unit1)
		unit1.save()

		def project1 = new Project(name: "Project 1", description: "empty")
		unit1.addToProjects(project1)
		project1.save()

		params.do_action = 'update'
		request.JSON = [id: 1, description: "not empty", name: "Hidden Project"]
		controller.project(request)

		assert response.status == 200
		assert [root: [id: 1, name: 'Hidden Project', description: "not empty"]] == response.json
		assert Organisation.count() == 1
		assert Unit.count() == 1
		assert Project.count() == 1
	}

	void testUpdateEmployee() {
		def org = new Organisation(name: "Main", description: "description goes here")
		org.save()

		def unit1 = new Unit(name: "Unit", description: "description")
		org.addToUnits(unit1)
		unit1.save()

		def project1 = new Project(name: "Project 1", description: "empty")
		unit1.addToProjects(project1)
		project1.save()

		def empl1 = new Employee(name: "Vasya", surName: "Pupkin", email:"vasya@mail.pu", birthDay: Date.parse("yyyy-MM-dd", "2009-09-15"), dateEmployed: Date.parse("yyyy-MM-dd", "2009-09-15"))
		project1.addToEmployees(empl1)
		empl1.save()

		params.do_action = 'update'
		request.JSON = [id: 1, name: "John", surName: "Coner", email:"johnconer@gmail.com", birthDay: Date.parse("yyyy-MM-dd", "1999-09-15"), dateEmployed: Date.parse("yyyy-MM-dd", "2029-09-15")]
		controller.employee(request)

		assert response.status == 200
		assert [root: [id: 1, name: "John", surName: "Coner", email:"johnconer@gmail.com", dateEmployed:'2029-09-13T20:00:00Z', birthDay:'1999-09-13T20:00:00Z']] == response.json
		assert Organisation.count() == 1
		assert Unit.count() == 1
		assert Project.count() == 1
		assert Employee.count() == 1
	}

	// ======================= REMOVE ======================= 

	void testRemoveUnit() {
		def org = new Organisation(name: "Main", description: "description goes here")
		org.save()

		def unit1 = new Unit(name: "Unit", description: "description")
		org.addToUnits(unit1)
		unit1.save()
		
		params.do_action = 'destroy'
		request.JSON = [id: "UNIT-1"]

		controller.orgTree(request)

		assert response.status == 200
		assert [root: [id: 1, name: "Unit", description: "description"]] == response.json
		assert Organisation.count() == 1
		assert Unit.count() == 0
	}

	void testRemoveProject() {
		def org = new Organisation(name: "Main", description: "description goes here")
		org.save()

		def unit1 = new Unit(name: "Unit", description: "description")
		org.addToUnits(unit1)
		unit1.save()
		
		def project1 = new Project(name: "Project 1", description: "empty")
		unit1.addToProjects(project1)
		project1.save()

		params.do_action = 'destroy'
		request.JSON = [id: "PROJ-1"]

		controller.orgTree(request)

		assert response.status == 200
		assert [root: [id: 1, name: "Project 1", description: "empty"]] == response.json
		assert Organisation.count() == 1
		assert Unit.count() == 1
		assert Project.count() == 0
	}

	void testRemoveEmployee() {
		def org = new Organisation(name: "Main", description: "description goes here")
		org.save()

		def unit1 = new Unit(name: "Unit", description: "description")
		org.addToUnits(unit1)
		unit1.save()
		
		def project1 = new Project(name: "Project 1", description: "empty")
		unit1.addToProjects(project1)
		project1.save()

		def empl1 = new Employee(name: "Vasya", surName: "Pupkin", email:"vasya@mail.pu", birthDay: Date.parse("yyyy-MM-dd", "2009-09-15"), dateEmployed: Date.parse("yyyy-MM-dd", "2009-09-15"))
		project1.addToEmployees(empl1)
		empl1.save()

		params.do_action = 'destroy'
		request.JSON = [id: "EMPL-1"]

		controller.orgTree(request)

		assert response.status == 200
		assert [root: [id: 1, name: "Vasya", surName: "Pupkin", email:"vasya@mail.pu", dateEmployed:'2009-09-14T20:00:00Z', birthDay:'2009-09-14T20:00:00Z']] == response.json
		assert Organisation.count() == 1
		assert Unit.count() == 1
		assert Project.count() == 1
		assert Employee.count() == 0
	}

	// ======================= FAILURE =======================

	void testUpdateOrgTree() {
		def org = new Organisation(name: "Main", description: "description goes here")
		org.save()

		params.do_action = 'update'
		request.JSON = [id: 1, description: "new description goes here", name: "Organisation"]
		controller.orgTree(request)

		assert response.status == 404
		assert '' == response.text
		assert Organisation.count() == 1
		assert Unit.count() == 0
		assert Project.count() == 0
		assert Employee.count() == 0
	}

	void testDestroyOrganisation() {
		def org = new Organisation(name: "Main", description: "description goes here")
		org.save()

		params.do_action = 'destroy'
		request.JSON = [id: 1]
		controller.organisation(request)

		assert response.status == 404
		assert Organisation.count() == 1
		assert '' == response.text
	}

	void testCreateOrganisation() {
		params.do_action = 'create'
		request.JSON = [name: "Main", description: "description goes here"]
		controller.organisation(request)

		assert response.status == 404
		assert Organisation.count() == 0
		assert '' == response.text
	}

	void testDestroyUnit() {
		def org = new Organisation(name: "Unit", description: "description goes here")
		org.save()

		def unit1 = new Unit(name: "Unit", description: "description")
		org.addToUnits(unit1)
		unit1.save()

		params.do_action = 'destroy'
		request.JSON = [id: 1]
		controller.unit(request)

		assert response.status == 404
		assert '' == response.text
		assert Organisation.count() == 1
		assert Unit.count() == 1
	}

	void testCreateUnit() {
		def org = new Organisation(name: "Unit", description: "description goes here")
		org.save()

		params.do_action = 'create'
		request.JSON = [name: "Unit", description: "description goes here"]
		controller.unit(request)

		assert response.status == 404
		assert '' == response.text
		assert Organisation.count() == 1
		assert Unit.count() == 0
	}

	void testDestroyProject() {
		def org = new Organisation(name: "Unit", description: "description goes here")
		org.save()

		def unit1 = new Unit(name: "Unit", description: "description")
		org.addToUnits(unit1)
		unit1.save()

		def project1 = new Project(name: "Project 1", description: "empty")
		unit1.addToProjects(project1)
		project1.save()

		params.do_action = 'destroy'
		request.JSON = [id: 1]
		controller.project(request)

		assert response.status == 404
		assert '' == response.text
		assert Organisation.count() == 1
		assert Unit.count() == 1
		assert Project.count() == 1
	}

	void testCreateProject() {
		def org = new Organisation(name: "Unit", description: "description goes here")
		org.save()

		def unit1 = new Unit(name: "Unit", description: "description")
		org.addToUnits(unit1)
		unit1.save()

		params.do_action = 'create'
		request.JSON = [name: "Project 1", description: "description goes here"]
		controller.project(request)

		assert response.status == 404
		assert '' == response.text
		assert Organisation.count() == 1
		assert Unit.count() == 1
		assert Project.count() == 0
	}

	void testDestroyEmployee() {
		def org = new Organisation(name: "Unit", description: "description goes here")
		org.save()

		def unit1 = new Unit(name: "Unit", description: "description")
		org.addToUnits(unit1)
		unit1.save()

		def project1 = new Project(name: "Project 1", description: "empty")
		unit1.addToProjects(project1)
		project1.save()

		def empl1 = new Employee(name: "Vasya", surName: "Pupkin", email:"vasya@mail.pu", birthDay: Date.parse("yyyy-MM-dd", "2009-09-15"), dateEmployed: Date.parse("yyyy-MM-dd", "2009-09-15"))
		project1.addToEmployees(empl1)
		empl1.save()

		params.do_action = 'destroy'
		request.JSON = [id: 1]
		controller.employee(request)

		assert response.status == 404
		assert '' == response.text
		assert Organisation.count() == 1
		assert Unit.count() == 1
		assert Project.count() == 1
		assert Employee.count() == 1
	}

	void testCreateEmployee() {
		def org = new Organisation(name: "Unit", description: "description goes here")
		org.save()

		def unit1 = new Unit(name: "Unit", description: "description")
		org.addToUnits(unit1)
		unit1.save()

		def project1 = new Project(name: "Project 1", description: "empty")
		unit1.addToProjects(project1)
		project1.save()

		params.do_action = 'create'
		request.JSON = [name: "John", surName: "Coner", email:"johnconer@gmail.com", dateEmployed:'2029-09-13T20:00:00Z', birthDay:'1999-09-13T20:00:00Z']
		controller.employee(request)

		assert response.status == 404
		assert '' == response.text
		assert Organisation.count() == 1
		assert Unit.count() == 1
		assert Project.count() == 1
		assert Employee.count() == 0
	}

	// ======================= UNSUPORTED =======================

	void testUnsuportedActions() {

		params.do_action = 'erase'
		controller.orgTree(request)
		assert response.status == 404
		assert '' == response.text

		controller.organisation(request)
		assert response.status == 404
		assert '' == response.text

		controller.unit(request)
		assert response.status == 404
		assert '' == response.text

		controller.project(request)
		assert response.status == 404
		assert '' == response.text

		controller.employee(request)
		assert response.status == 404
		assert '' == response.text
	}

	// ======================= BAD ID =======================

	void testReadBadTree() {
		def org = new Organisation(name: "Main", description: "description goes here")
		org.save()

		def unit1 = new Unit(name: "Unit", description: "description")
		org.addToUnits(unit1)
		unit1.save()
		
		def project1 = new Project(name: "Project 1", description: "empty")
		unit1.addToProjects(project1)
		project1.save()

		def empl1 = new Employee(name: "Vasya", surName: "Pupkin", email:"vasya@mail.pu", birthDay: Date.parse("yyyy-MM-dd", "2009-09-15"), dateEmployed: Date.parse("yyyy-MM-dd", "2009-09-15"))
		project1.addToEmployees(empl1)
		empl1.save()

		params.do_action = 'read'
		params.node = 'other_than_root'
		controller.orgTree(request)

		assert '' == response.text
		assert response.status == 404
		assert Organisation.count() == 1
		assert Unit.count() == 1
		assert Project.count() == 1
		assert Employee.count() == 1
	}

	void testBadDestroyOrgTree() {
		def org = new Organisation(name: "Main", description: "description goes here")
		org.save()

		def unit1 = new Unit(name: "Unit", description: "description")
		org.addToUnits(unit1)
		unit1.save()
		
		params.do_action = 'destroy'
		request.JSON = [id: "UNT-1"]
		controller.orgTree(request)

		assert response.status == 404
		assert '' == response.text
		assert Organisation.count() == 1
		assert Unit.count() == 1
	}

	void testBadDestroyOrgTree2() {
		def org = new Organisation(name: "Main", description: "description goes here")
		org.save()

		def unit1 = new Unit(name: "Unit", description: "description")
		org.addToUnits(unit1)
		unit1.save()
		
		params.do_action = 'destroy'
		controller.orgTree(request)

		assert response.status == 404
		assert '' == response.text
		assert Organisation.count() == 1
		assert Unit.count() == 1
	}

	void testBadCreateOrgTree() {
		def org = new Organisation(name: "Main", description: "description goes here")
		org.save()

		def unit1 = new Unit(name: "Unit", description: "description")
		org.addToUnits(unit1)
		unit1.save()

		params.do_action = 'create'
		request.JSON = [parentId: "UNT-1"]
		controller.orgTree(request)

		assert response.status == 404
		assert '' == response.text

		assert Organisation.count() == 1
		assert Unit.count() == 1
	}

	void testBadCreateOrgTree2() {
		def org = new Organisation(name: "Main", description: "description goes here")
		org.save()

		def unit1 = new Unit(name: "Unit", description: "description")
		org.addToUnits(unit1)
		unit1.save()

		params.do_action = 'create'
		controller.orgTree(request)

		assert response.status == 404
		assert '' == response.text

		assert Organisation.count() == 1
		assert Unit.count() == 1
	}

	void testBadId() {
		def org = new Organisation(name: "Main", description: "description goes here")
		org.save()

		def unit1 = new Unit(name: "Unit", description: "description")
		org.addToUnits(unit1)
		unit1.save()
		
		def project1 = new Project(name: "Project 1", description: "empty")
		unit1.addToProjects(project1)
		project1.save()

		def empl1 = new Employee(name: "Vasya", surName: "Pupkin", email:"vasya@mail.pu", birthDay: Date.parse("yyyy-MM-dd", "2009-09-15"), dateEmployed: Date.parse("yyyy-MM-dd", "2009-09-15"))
		project1.addToEmployees(empl1)
		empl1.save()


		params.do_action = 'read'
		params.JSON = [id: 3]

		controller.organisation(request)
		assert '' == response.text
		assert response.status == 404

		controller.unit(request)
		assert '' == response.text
		assert response.status == 404

		controller.project(request)
		assert '' == response.text
		assert response.status == 404

		controller.employee(request)
		assert '' == response.text
		assert response.status == 404

		params.do_action = 'update'

		controller.organisation(request)
		assert '' == response.text
		assert response.status == 404

		controller.unit(request)
		assert '' == response.text
		assert response.status == 404

		controller.project(request)
		assert '' == response.text
		assert response.status == 404

		controller.employee(request)
		assert '' == response.text
		assert response.status == 404

		assert Organisation.count() == 1
		assert Unit.count() == 1
		assert Project.count() == 1
		assert Employee.count() == 1
	}
}
